//RendererD3D11.h
//Created 25/11/13
//Created By Daniel Bowler
//
//Manager class - created and managed by the interface - that is essentially
//a bunch of functions that render geometry. The interface will pick the right
//one per set of render data.

#pragma once

//Include needed D3D related headers and XNA maths.
#include "d3dUtil.h"

//Forward declare debug quad draw effect
class TexturedFullScreenQuadFX;

//Forward declare effects.
class TileForwardTextureMapFX;
class TileForwardNormalMapFX;
class TileForwardDisplacementMappingFX;
class TileForwardSolidColourFX;

//Instancing effects. 
class TileForwardNormalMapInstFX;
class TileForwardTextureMapInstFX;
class TileForwardSolidColourInstFX;
class TileForwardDisplacementMapInstFX;

//Animation effects
class TileForwardAnimNormalMapFX;
class TileForwardAnimTextureMapFX;
class TileForwardAnimSolidColourFX;

class D3D11Renderer
{
public:
	//Class is a singleton
	static D3D11Renderer* GetInstance();
	void Release();
	
public:
	//Draws the texture to the screen. 
	void DebugDrawTexture(ID3D11DeviceContext* context, 
		ID3D11Buffer* vb, ID3D11Buffer* ib, 
		ID3D11ShaderResourceView* tex,
		CXMMATRIX &proj,
		bool msaaTex,
		LPCSTR techName);

public:
	//Rendering functions. Interacts with D3D11/Effects framework to draw geometry to the screen
	//(Or to the depth buffer in the Z pre pass stage for that matter)
	//
	//Renders a model with a texture applied. 
	void RenderWithTileForwardTextureMapFX(
		ID3D11DeviceContext* context,
		XMFLOAT3& eyePosition, DirectionalLight* dLights, unsigned dLightCount, 
		ID3D11ShaderResourceView* llib, ID3D11ShaderResourceView* llseb,
		ID3D11Buffer* vb, ID3D11Buffer* ib, 
		CXMMATRIX& world, CXMMATRIX& worldInvTrans, CXMMATRIX& worldViewProj, CXMMATRIX& texTrans, 
		Material& mat, 
		ID3D11ShaderResourceView* texture,
		unsigned drawCount,
		unsigned drawStart,
		bool isZPrePass, 
		D3D11_PRIMITIVE_TOPOLOGY topology, 
		XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange, 
		CXMMATRIX& worldView, 
		ID3D11ShaderResourceView* ssaoTex,
		CXMMATRIX& SSAOTrans, 
		ID3D11ShaderResourceView* envMap, 
		bool isShadowPass, 
		ID3D11ShaderResourceView* shadMap,
		CXMMATRIX &shadowMapView, 
		CXMMATRIX &shadowMapProj, 
		CXMMATRIX &shadowMapToTex, 
		bool shouldSampleSSAO);

	//Render a model with a texture and normal map applied. 
	void RenderWithTileForwardNormalMapFX(
		ID3D11DeviceContext* context,
		XMFLOAT3& eyePosition, DirectionalLight* dLights, unsigned dLightCount, 
		ID3D11ShaderResourceView* llib, ID3D11ShaderResourceView* llseb,
		ID3D11Buffer* vb, ID3D11Buffer* ib, 
		CXMMATRIX& world, CXMMATRIX& worldInvTrans, CXMMATRIX& worldViewProj, CXMMATRIX& texTrans, 
		Material& mat, 
		ID3D11ShaderResourceView* texture,
		ID3D11ShaderResourceView* normalMap,
		unsigned drawCount,
		unsigned drawStart,
		bool isZPrePass, 
		D3D11_PRIMITIVE_TOPOLOGY topology, 
		XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange, 
		CXMMATRIX& worldView, 
		ID3D11ShaderResourceView* ssaoTex,
		CXMMATRIX& SSAOTrans, 
		ID3D11ShaderResourceView* envMap, 
		bool isShadowPass, 
		ID3D11ShaderResourceView* shadMap,
		CXMMATRIX &shadowMapView, 
		CXMMATRIX &shadowMapProj, 
		CXMMATRIX &shadowMapToTex, 
		bool shouldSampleSSAO);

	//Render a model with a texture and displacement map. 
	void RenderWithTileForwardDisplacementMapFX(
		ID3D11DeviceContext* context,
		XMFLOAT3& eyePosition, DirectionalLight* dLights, unsigned dLightCount, 
		ID3D11ShaderResourceView* llib, ID3D11ShaderResourceView* llseb,
		ID3D11Buffer* vb, ID3D11Buffer* ib, 
		CXMMATRIX& world, CXMMATRIX& viewProj, CXMMATRIX& worldInvTrans, CXMMATRIX& worldViewProj, 
		CXMMATRIX& texTrans, 
		Material& mat, 
		ID3D11ShaderResourceView* texture,
		ID3D11ShaderResourceView* dispMap,
		ID3D11ShaderResourceView* heightMap, //Optional.
		float heightScale, 
		float maxTessDist, float minTessDist, 
		float maxTessFact, float minTessFact,
		unsigned drawCount,
		unsigned drawStart,
		bool isZPrePass, 
		D3D11_PRIMITIVE_TOPOLOGY topology, 
		XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange, 
		CXMMATRIX& worldView, CXMMATRIX& view, 
		ID3D11ShaderResourceView* ssaoTex,
		CXMMATRIX& SSAOTrans, 
		ID3D11ShaderResourceView* envMap, 
		bool isShadowPass, 
		ID3D11ShaderResourceView* shadMap,
		CXMMATRIX &shadowMapView, 
		CXMMATRIX &shadowMapProj, 
		CXMMATRIX &shadowMapToTex, 
		bool shouldSampleSSAO);

	//Render a model with a solid colour
	void RenderWithTileForwardSolidColourFX(
		ID3D11DeviceContext* context,
		XMFLOAT3& eyePosition, DirectionalLight* dLights, unsigned dLightCount, 
		ID3D11ShaderResourceView* llib, ID3D11ShaderResourceView* llseb,
		ID3D11Buffer* vb, ID3D11Buffer* ib, 
		CXMMATRIX& world, CXMMATRIX& worldInvTrans, CXMMATRIX& worldViewProj, 
		Material& mat, 
		XMFLOAT3& modelColour, 
		unsigned drawCount, 
		unsigned drawStart, 
		bool isZPrePass, 
		D3D11_PRIMITIVE_TOPOLOGY topology, 
		XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange, 
		CXMMATRIX& worldView, 
		ID3D11ShaderResourceView* ssaoTex,
		CXMMATRIX& SSAOTrans, 
		ID3D11ShaderResourceView* envMap, 
		bool isShadowPass, 
		ID3D11ShaderResourceView* shadMap,
		CXMMATRIX &shadowMapView, 
		CXMMATRIX &shadowMapProj, 
		CXMMATRIX &shadowMapToTex, 
		bool shouldSampleSSAO);

	//Renders a model with a normal map (instanced).
	void RenderWithTileForwardNormalMapInstFX(ID3D11DeviceContext* context,
		XMFLOAT3& eyePosition, DirectionalLight* dLights, unsigned dLightCount, 
		ID3D11ShaderResourceView* llib, ID3D11ShaderResourceView* llseb,
		ID3D11Buffer* vb, ID3D11Buffer* ib, 
		ID3D11Buffer* instVertexBuffer,
		CXMMATRIX& viewProj, CXMMATRIX& texTrans, 
		Material& mat, 
		ID3D11ShaderResourceView* texture,
		ID3D11ShaderResourceView* normalMap,
		unsigned drawCount,
		unsigned drawStart,
		unsigned instanceCount,
		bool isZPrePass, 
		D3D11_PRIMITIVE_TOPOLOGY topology, 
		XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange, 
		CXMMATRIX& view, 
		ID3D11ShaderResourceView* ssaoTex,
		CXMMATRIX& SSAOToTexMatrix, 
		ID3D11ShaderResourceView* envMap, 
		bool isShadowPass, 
		ID3D11ShaderResourceView* shadMap,
		CXMMATRIX &shadowMapView, 
		CXMMATRIX &shadowMapProj, 
		CXMMATRIX &shadowMapToTex);

	//Renders a model with a texture map (instanced)
	void RenderWithTileForwardTextureMapInstFX(ID3D11DeviceContext* context,
		XMFLOAT3& eyePosition, DirectionalLight* dLights, unsigned dLightCount, 
		ID3D11ShaderResourceView* llib, ID3D11ShaderResourceView* llseb,
		ID3D11Buffer* vb, ID3D11Buffer* ib, 
		ID3D11Buffer* instVertexBuffer,
		CXMMATRIX& viewProj, CXMMATRIX& texTrans, 
		Material& mat, 
		ID3D11ShaderResourceView* texture,
		unsigned drawCount,
		unsigned drawStart,
		unsigned instanceCount,
		bool isZPrePass, 
		D3D11_PRIMITIVE_TOPOLOGY topology, 
		XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange, 
		CXMMATRIX& view, 
		ID3D11ShaderResourceView* ssaoTex,
		CXMMATRIX& SSAOToTexMatrix, 
		ID3D11ShaderResourceView* envMap, 
		bool isShadowPass, 
		ID3D11ShaderResourceView* shadMap,
		CXMMATRIX &shadowMapView, 
		CXMMATRIX &shadowMapProj, 
		CXMMATRIX &shadowMapToTex);

	//Render a model with a solid colour (Instanced)
	void RenderWithTileForwardSolidColourInstFX(
		ID3D11DeviceContext* context,
		XMFLOAT3& eyePosition, DirectionalLight* dLights, unsigned dLightCount, 
		ID3D11ShaderResourceView* llib, ID3D11ShaderResourceView* llseb,
		ID3D11Buffer* vb, ID3D11Buffer* ib, 
		ID3D11Buffer* instancedBuffer,
		CXMMATRIX& viewProj,
		Material& mat, 
		XMFLOAT3& modelColour, 
		unsigned drawCount, 
		unsigned drawStart, 
		unsigned instanceCount,
		bool isZPrePass, 
		D3D11_PRIMITIVE_TOPOLOGY topology, 
		XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange, 
		CXMMATRIX& view, 
		ID3D11ShaderResourceView* ssaoTex,
		CXMMATRIX& SSAOToTexMatrix, 
		ID3D11ShaderResourceView* envMap, 
		bool isShadowPass, 
		ID3D11ShaderResourceView* shadMap,
		CXMMATRIX &shadowMapView, 
		CXMMATRIX &shadowMapProj, 
		CXMMATRIX &shadowMapToTex);

	//Render a model with displacement mapping (Instanced)
	void RenderWithTileForwardDisplacementMapInstFX(
		ID3D11DeviceContext* context,
		XMFLOAT3& eyePosition, DirectionalLight* dLights, unsigned dLightCount, 
		ID3D11ShaderResourceView* llib, ID3D11ShaderResourceView* llseb,
		ID3D11Buffer* vb, ID3D11Buffer* ib, 
		ID3D11Buffer* instancedBuffer,
		CXMMATRIX& viewProj, CXMMATRIX& texTrans, 
		Material& mat, 
		ID3D11ShaderResourceView* texture,
		ID3D11ShaderResourceView* dispMap,
		ID3D11ShaderResourceView* heightMap, //Optional (Seperate height map)
		float heightScale, 
		float maxTessDist, float minTessDist, 
		float maxTessFact, float minTessFact,
		unsigned drawCount,
		unsigned drawStart,
		unsigned instanceCount,
		bool isZPrePass, 
		D3D11_PRIMITIVE_TOPOLOGY topology, 
		XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange, 
		CXMMATRIX& view, 
		ID3D11ShaderResourceView* ssaoTex,
		CXMMATRIX& SSAOToTexMatrix, 
		ID3D11ShaderResourceView* envMap, 
		bool isShadowPass, 
		ID3D11ShaderResourceView* shadMap,
		CXMMATRIX &shadowMapView, 
		CXMMATRIX &shadowMapProj, 
		CXMMATRIX &shadowMapToTex);

	//Renders animating (sub)model with a normal map applied. 
	void RenderWithTileForwardAnimNormalMapFX(
		ID3D11DeviceContext* context,
		XMFLOAT3& eyePosition, DirectionalLight* dLights, unsigned dLightCount, 
		ID3D11ShaderResourceView* llib, ID3D11ShaderResourceView* llseb,
		ID3D11Buffer* vb, ID3D11Buffer* ib, 
		CXMMATRIX& world, CXMMATRIX& worldInvTrans, CXMMATRIX& worldViewProj, CXMMATRIX& texTrans, 
		Material& mat, 
		ID3D11ShaderResourceView* texture,
		ID3D11ShaderResourceView* normalMap,
		unsigned drawCount,
		unsigned drawStart,
		bool isZPrePass, 
		D3D11_PRIMITIVE_TOPOLOGY topology, 
		XMFLOAT4X4* finalTransforms, unsigned boneCount, 
		XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange, 
		CXMMATRIX& worldView, 
		ID3D11ShaderResourceView* ssaoTex,
		CXMMATRIX& SSAOTrans, 
		ID3D11ShaderResourceView* envMap, 
		bool isShadowPass, 
		ID3D11ShaderResourceView* shadMap,
		CXMMATRIX &shadowMapView, 
		CXMMATRIX &shadowMapProj, 
		CXMMATRIX &shadowMapToTex);

	//Renders animating (sub)model with a texture map applied. 
	void RenderWithTileForwardAnimTextureMapFX(ID3D11DeviceContext* context,
		XMFLOAT3& eyePosition, DirectionalLight* dLights, unsigned dLightCount, 
		ID3D11ShaderResourceView* llib, ID3D11ShaderResourceView* llseb,
		ID3D11Buffer* vb, ID3D11Buffer* ib, 
		CXMMATRIX& world, CXMMATRIX& worldInvTrans, CXMMATRIX& worldViewProj, CXMMATRIX& texTrans, 
		Material& mat, 
		ID3D11ShaderResourceView* texture,
		unsigned drawCount,
		unsigned drawStart,
		bool isZPrePass, 
		D3D11_PRIMITIVE_TOPOLOGY topology, 
		XMFLOAT4X4* finalTransforms, unsigned boneCount, 
		XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange, 
		CXMMATRIX& worldView, 
		ID3D11ShaderResourceView* ssaoTex,
		CXMMATRIX& SSAOTrans, 
		ID3D11ShaderResourceView* envMap, 
		bool isShadowPass, 
		ID3D11ShaderResourceView* shadMap,
		CXMMATRIX &shadowMapView, 
		CXMMATRIX &shadowMapProj, 
		CXMMATRIX &shadowMapToTex);

	//Renders animating submodel with a solid colour
	void RenderWithTileForwardAnimSolidColourFX(
		ID3D11DeviceContext* context,
		XMFLOAT3& eyePosition, DirectionalLight* dLights, unsigned dLightCount, 
		ID3D11ShaderResourceView* llib, ID3D11ShaderResourceView* llseb,
		ID3D11Buffer* vb, ID3D11Buffer* ib, 
		CXMMATRIX& world, CXMMATRIX& worldInvTrans, CXMMATRIX& worldViewProj, 
		Material& mat, 
		XMFLOAT3& modelColour, 
		unsigned drawCount, 
		unsigned drawStart, 
		bool isZPrePass, 
		D3D11_PRIMITIVE_TOPOLOGY topology,
		XMFLOAT4X4* finalTransforms, unsigned boneCount, 
		XMFLOAT3 &hemiColDown, XMFLOAT3 &hemiColRange, 
		CXMMATRIX& worldView, 
		ID3D11ShaderResourceView* ssaoTex,
		CXMMATRIX& SSAOTrans, 
		ID3D11ShaderResourceView* envMap, 
		bool isShadowPass, 
		ID3D11ShaderResourceView* shadMap,
		CXMMATRIX &shadowMapView, 
		CXMMATRIX &shadowMapProj, 
		CXMMATRIX &shadowMapToTex);

private:
	//Effect pointers.
	//
	//Debug draw quad. 
	TexturedFullScreenQuadFX* debugDrawTexQuadEffect;

	//Non instancing effects.
	TileForwardTextureMapFX* textureMappingEffect;
	TileForwardNormalMapFX* normalMappingEffect;
	TileForwardDisplacementMappingFX* displacementMappingEffect;
	TileForwardSolidColourFX* tileForwardSolidColourEffect;

	//Instancing effects.
	TileForwardNormalMapInstFX* normalMappingInstEffect;
	TileForwardTextureMapInstFX* textureMappingInstEffect;
	TileForwardSolidColourInstFX* solidColourInstEffect;
	TileForwardDisplacementMapInstFX* dispMappingInstEffect;

	//Animation effects
	TileForwardAnimNormalMapFX* animNormalMapFX;
	TileForwardAnimTextureMapFX* animTexMapFX;
	TileForwardAnimSolidColourFX* animSolidColourFX;

private:
	//Make singleton
	static D3D11Renderer* instance; 
	//Hide constructor, destructor, copy constructor and assignment
	//operator
	D3D11Renderer();
	~D3D11Renderer();
	D3D11Renderer(D3D11Renderer& other);
	D3D11Renderer& operator=(D3D11Renderer& other);
};